﻿using System;
using Styx;
using Styx.Helpers;
using Styx.Pathing;
using Styx.TreeSharp;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;

namespace TuanHA_Hunter
{
    public partial class Classname
    {
        #region Delegates

        public delegate float DynamicRangeRetriever(object context);

        public delegate WoWPoint LocationRetriever(object context);

        public delegate bool SimpleBooleanDelegate(object context);

        public delegate WoWUnit UnitSelectionDelegate(object context);

        #endregion

        //private static bool IsMovingBehind = false;
        //private static TimeSpan MovementDelay = TimeSpan.FromSeconds(0);
        //private static DateTime LastMovementTime = new DateTime(1970, 1, 1);
        //private static WoWPoint LastMovementWoWPoint;
        //private static float DistanceToUpdateMovement = 3f;
        //private static float DistanceToMelee;

        private static WoWPoint LastMovementWoWPoint;
        //Set Distance To Keep in Melee Range base on Unit type
        private static float Dtm(WoWUnit toUnit)
        {
            if (toUnit.IsPlayer)
            {
                return 3;
            }
            return 5;
        }

        private static Composite MovementMoveStop(UnitSelectionDelegate toUnit, int range)
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoMove &&
                !IsOverrideModeOn &&
                toUnit != null &&
                toUnit(ret) != null &&
                toUnit(ret).IsValid &&
                toUnit(ret) != Me &&
                toUnit(ret).IsAlive &&
                Me.IsMoving &&
                toUnit(ret).Distance <= range &&
                toUnit(ret).InLineOfSpellSight,
                new Action(ret =>
                    {
                        Navigator.PlayerMover.MoveStop();
                        return RunStatus.Failure;
                    }));
        }

        private static Composite MovementMoveToLoS(UnitSelectionDelegate toUnit)
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoMove &&
                !Me.Mounted &&
                !IsOverrideModeOn &&
                !Casting() &&
                toUnit != null &&
                toUnit(ret) != null &&
                toUnit(ret).IsValid &&
                toUnit(ret) != Me &&
                (!toUnit(ret).InLineOfSpellSight || toUnit(ret).Distance > THSettings.Instance.DistanceRange),
                new Action(ret =>
                    {
                        LastMovementWoWPoint = toUnit(ret).Location;
                        Navigator.MoveTo(LastMovementWoWPoint);
                        return RunStatus.Failure;
                    }));
        }

        private static Composite MovementMoveToMelee(UnitSelectionDelegate toUnit)
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoMove &&
                !Me.Mounted &&
                !IsOverrideModeOn &&
                !Casting() &&
                toUnit != null &&
                toUnit(ret) != null &&
                toUnit(ret).IsValid &&
                toUnit(ret) != Me &&
                toUnit(ret).IsAlive &&
                (toUnit(ret).Distance - toUnit(ret).BoundingRadius > Dtm(toUnit(ret)) ||
                 !toUnit(ret).IsWithinMeleeRange),
                new Action(ret =>
                    {
                        LastMovementWoWPoint = toUnit(ret).Location;
                        Navigator.MoveTo(LastMovementWoWPoint);
                        return RunStatus.Failure;
                    }));
        }

        private static Composite MovementMoveBehind(UnitSelectionDelegate toUnit)
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoMove &&
                !Me.Mounted &&
                !IsOverrideModeOn &&
                !Casting() &&
                toUnit != null &&
                toUnit(ret) != null &&
                toUnit(ret).IsValid &&
                toUnit(ret) != Me &&
                toUnit(ret).IsAlive &&
                //only MovementMoveBehind if IsWithinMeleeRange
                !toUnit(ret).IsMoving &&
                (toUnit(ret).Distance < Dtm(toUnit(ret)) ||
                 toUnit(ret).IsWithinMeleeRange) &&
                !Me.IsBehind(toUnit(ret)) &&
                !MeIsTank &&
                (toUnit(ret).IsPlayer ||
                 !toUnit(ret).IsPlayer && toUnit(ret).CurrentTarget != Me && toUnit(ret).Combat),
                new Action(ret =>
                    {
                        WoWPoint pointBehind =
                            toUnit(ret).Location.RayCast(
                                toUnit(ret).Rotation + WoWMathHelper.DegreesToRadians(150), 3f);
                        LastMovementWoWPoint = pointBehind;

                        Navigator.MoveTo(pointBehind);
                        return RunStatus.Failure;
                    }));
        }
    }
}